#!/usr/bin/env python3
"""
优化的 EXE 打包脚本
使用 PyInstaller 打包 Meiya SQL 生成工具，并进行文件大小优化

使用方法：
python build_exe.py

需要安装 PyInstaller：
pip install pyinstaller
"""

import os
import sys
import shutil
import subprocess
from pathlib import Path

def check_requirements():
    """检查打包所需的工具"""
    print("🔍 检查打包环境...")
    
    # 检查 PyInstaller
    try:
        import PyInstaller
        print(f"✅ PyInstaller 已安装: {PyInstaller.__version__}")
    except ImportError:
        print("❌ 需要安装 PyInstaller: pip install pyinstaller")
        return False
    
    # 检查主程序文件
    if not Path("gui_main.py").exists():
        print("❌ 找不到主程序文件: gui_main.py")
        return False
    
    # 检查 spec 文件
    spec_file = "Meiya-SQL生成工具.spec"
    if not Path(spec_file).exists():
        print(f"❌ 找不到 spec 文件: {spec_file}")
        return False
    
    # 检查图标文件
    icon_file = "app_icon.ico"
    if not Path(icon_file).exists():
        print(f"⚠️  找不到图标文件: {icon_file}")
        print("   将使用默认图标，或者你可以:")
        print("   1. 准备一个 .ico 格式的图标文件")
        print("   2. 使用 convert_icon.py 转换其他格式的图片")
        
        # 暂时移除图标配置
        spec_content = Path(spec_file).read_text(encoding='utf-8')
        if "icon='app_icon.ico'" in spec_content:
            spec_content = spec_content.replace("icon='app_icon.ico',", "# icon='app_icon.ico',  # 图标文件不存在")
            Path(spec_file).write_text(spec_content, encoding='utf-8')
            print("   已暂时禁用图标配置")
    else:
        print(f"✅ 找到图标文件: {icon_file}")
    
    return True

def clean_build():
    """清理之前的构建文件"""
    print("🧹 清理旧的构建文件...")
    
    directories_to_clean = ["build", "dist", "__pycache__"]
    
    for dir_name in directories_to_clean:
        if Path(dir_name).exists():
            shutil.rmtree(dir_name)
            print(f"   删除: {dir_name}/")
    
    print("✅ 清理完成")

def build_exe():
    """执行打包"""
    print("🚀 开始打包...")
    
    spec_file = "Meiya-SQL生成工具.spec"
    
    # 执行 PyInstaller
    try:
        cmd = ["pyinstaller", "--clean", spec_file]
        print(f"📦 执行命令: {' '.join(cmd)}")
        
        result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8')
        
        if result.returncode == 0:
            print("✅ 打包成功！")
            return True
        else:
            print("❌ 打包失败！")
            print("错误输出:")
            print(result.stderr)
            return False
            
    except Exception as e:
        print(f"❌ 打包过程中出现错误: {e}")
        return False

def check_result():
    """检查打包结果"""
    print("📊 检查打包结果...")
    
    dist_dir = Path("dist")
    if not dist_dir.exists():
        print("❌ 没有找到 dist 目录")
        return False
    
    exe_files = list(dist_dir.glob("*.exe"))
    if not exe_files:
        print("❌ 没有找到 .exe 文件")
        return False
    
    for exe_file in exe_files:
        size_mb = exe_file.stat().st_size / (1024 * 1024)
        print(f"📁 生成的文件: {exe_file.name}")
        print(f"📏 文件大小: {size_mb:.2f} MB")
        
        if size_mb > 100:
            print("⚠️  文件较大，可以考虑进一步优化")
        elif size_mb < 50:
            print("✅ 文件大小适中")
    
    return True

def show_optimization_tips():
    """显示进一步优化建议"""
    print("\n💡 进一步优化建议:")
    print("1. 如果文件仍然较大，可以:")
    print("   - 在 .spec 文件的 excludes 列表中添加更多不需要的模块")
    print("   - 使用 --exclude-module 参数排除特定模块")
    print("   - 考虑使用 --onedir 模式而不是 --onefile")
    print()
    print("2. 如果需要添加图标:")
    print("   - 准备一个 .ico 格式的图标文件命名为 app_icon.ico")
    print("   - 或使用 convert_icon.py 转换其他格式的图片")
    print()
    print("3. 如果需要版本信息:")
    print("   - 可以创建版本信息文件并在 .spec 中配置")

def main():
    print("=" * 60)
    print("🚀 Meiya SQL 生成工具 - 优化打包脚本")
    print("=" * 60)
    
    # 检查环境
    if not check_requirements():
        print("💥 环境检查失败，请解决上述问题后重试")
        return 1
    
    # 清理旧文件
    clean_build()
    
    # 执行打包
    if not build_exe():
        print("💥 打包失败")
        return 1
    
    # 检查结果
    if not check_result():
        print("💥 打包结果检查失败")
        return 1
    
    # 显示优化建议
    show_optimization_tips()
    
    print("\n🎉 打包完成！生成的文件在 dist/ 目录中")
    return 0

if __name__ == "__main__":
    sys.exit(main())

